﻿// <copyright file="StringExtensions.cs" company="Lu Studio">
// Copyright (c) Lu Studio. All rights reserved.
// </copyright>
// <author>lu qi</author>
// <createTime>2021-07-25</createTime>
namespace ElfKit.Common
{
    using ElfKit.Common.Properties;
    using System;

    /// <summary>
    /// <see cref="string"/>子字符串扩展.
    /// </summary>
    public static partial class StringExtensions
    {
        #region Left

        /// <summary>
        /// 从<paramref name="value"/>左面截取<paramref name="length"/>长度的字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="length">截取长度.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <remarks>
        /// <para><paramref name="length"/>小于等于0 返回string.Empty</para>
        /// <para><paramref name="length"/>大于<paramref name="value"/>的长度返回<paramref name="value"/></para>
        /// </remarks>
        public static string Left(this string value, int length)
        {
            Guard.NotNull(value, nameof(value));
            if (length <= 0)
            {
                return string.Empty;
            }

            return length > value.Length ? value : value.Substring(0, length);
        }

        #endregion

        #region Right

        /// <summary>
        /// 从<paramref name="value"/>右面截取<paramref name="length"/>长度的字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="length">截取长度.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <remarks>
        /// <para><paramref name="length"/>小于等于0 返回string.Empty</para>
        /// <para><paramref name="length"/>大于<paramref name="value"/>的长度返回<paramref name="value"/></para>
        /// </remarks>
        public static string Right(this string value, int length)
        {
            Guard.NotNull(value, nameof(value));
            if (length <= 0)
            {
                return string.Empty;
            }

            return length > value.Length ? value : value.Substring(value.Length - length, length);
        }

        #endregion

        #region LeftOf

        #region char

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            char search)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search);
            return HandleLeftOf(value, search.ToString(), index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            char search,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, comparisonType);
            return HandleLeftOf(value, search.ToString(), index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <param name="startIndex">开始索引</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            char search,
            int startIndex)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex);
            return HandleLeftOf(value, search.ToString(), index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="count">搜索个数.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            char search,
            int startIndex,
            int count)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, count);
            return HandleLeftOf(value, search.ToString(), index);
        }

        #endregion

        #region string

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            string search)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search);
            return HandleLeftOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            string search,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, comparisonType);
            return HandleLeftOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            string search,
            int startIndex)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex);
            return HandleLeftOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="count">搜索个数.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            string search,
            int startIndex,
            int count)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, count);
            return HandleLeftOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            string search,
            int startIndex,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, comparisonType);
            return HandleLeftOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="count">搜索个数.</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string LeftOf(
            this string value,
            string search,
            int startIndex,
            int count,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, count, comparisonType);
            return HandleLeftOf(value, search, index);
        }

        #endregion

        #endregion

        #region RightOf

        #region char

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            char search)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search);
            return HandleRightOf(value, search.ToString(), index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            char search,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, comparisonType);
            return HandleRightOf(value, search.ToString(), index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <param name="startIndex">开始索引</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            char search,
            int startIndex)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex);
            return HandleRightOf(value, search.ToString(), index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="count">搜索个数.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            char search,
            int startIndex,
            int count)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, count);
            return HandleRightOf(value, search.ToString(), index);
        }

        #endregion

        #region string

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            string search)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search);
            return HandleRightOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            string search,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, comparisonType);
            return HandleRightOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            string search,
            int startIndex)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex);
            return HandleRightOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="count">搜索个数.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            string search,
            int startIndex,
            int count)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, count);
            return HandleRightOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            string search,
            int startIndex,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, comparisonType);
            return HandleRightOf(value, search, index);
        }

        /// <summary>
        /// 从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="count">搜索个数.</param>
        /// <param name="comparisonType"><see cref="StringComparison"/>比较类型.</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="value"/>is null.</exception>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        public static string RightOf(
            this string value,
            string search,
            int startIndex,
            int count,
            StringComparison comparisonType)
        {
            Guard.NotNull(value, nameof(value));

            int index = value.IndexOf(search, startIndex, count, comparisonType);
            return HandleRightOf(value, search, index);
        }

        #endregion

        #endregion

        #region 内部函数

        /// <summary>
        /// 处理从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的左面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="index">搜索字符串在<paramref name="value"/>中第一个符合的字符串的索引</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        private static string HandleLeftOf(string value, string search, int index)
        {
            return index == Constant.NotFound
                ? throw new ArgumentException(Localization.Format<Resources>(nameof(Resources.NotFound), search), nameof(search))
                : value.Substring(0, index);
        }

        /// <summary>
        /// 处理从<paramref name="value"/>中截取第一个符合<paramref name="search"/>字符串的右面的所有字符串.
        /// </summary>
        /// <param name="value">字符串.</param>
        /// <param name="search">搜索字符串.</param>
        /// <param name="index">搜索字符串在<paramref name="value"/>中第一个符合的字符串的索引</param>
        /// <returns>截取后的字符串.</returns>
        /// <exception cref="System.ArgumentException"><paramref name="search"/>not found in <paramref name="value"/>.</exception>
        private static string HandleRightOf(string value, string search, int index)
        {
            return index == Constant.NotFound
                ? throw new ArgumentException(Localization.Format<Resources>(nameof(Resources.NotFound), search), nameof(search))
                : value.Substring(index + 1, value.Length - index - 1);
        }

        #endregion
    }
}